using System;
using System.IO;
using System.Linq;
using System.Text;
using System.Windows.Media.Imaging;
using Legacy.Core.SaveGameManagement;

namespace MMXSaveGameConverter
{
    internal sealed class SaveFileReader : FileReaderBase
    {
        private readonly string _savePath;

        public SaveFileReader(string savePath)
        {
            _savePath = savePath;
        }

        public override IReaderState Read()
        {
            return new SaveReadState(_savePath);
        }

        public override SaveFileMeta ReadFileMeta(IReaderState readerState)
        {
            SaveReadState state = (SaveReadState)readerState;
            if (state.FileMetaReaded)
                throw new InvalidOperationException();

            state.FileMetaReaded = true;

            return SaveFileMeta.FromSave(state.SaveInput);
        }

        public override SaveGameMeta ReadSaveMeta(IReaderState readerState)
        {
            SaveReadState state = (SaveReadState)readerState;
            if (!state.FileMetaReaded || state.SaveMetaReaded)
                throw new InvalidOperationException();

            state.SaveMetaReaded = true;
            BinaryReader br = new BinaryReader(state.SaveInput, Encoding.Default);
                return SaveGame.ReadMetaData(br);
        }

        public override SaveGame ReadSaveGame(IReaderState readerState, SaveGameMeta saveMeta)
        {
            SaveReadState state = (SaveReadState)readerState;
            if (!state.FileMetaReaded || !state.SaveMetaReaded || state.SaveGameReaded)
                throw new InvalidOperationException();

            state.SaveGameReaded = true;
            BinaryReader br = new BinaryReader(state.SaveInput, Encoding.Default);
            SaveGame result = new SaveGame(saveMeta);

            int num = br.ReadInt32();
            for (int index = 0; index < num; index++)
            {
                string str = br.ReadString();
                SaveGameData saveGameData = new SaveGameData(str);
                saveGameData.Read(br);
                result.Add(saveGameData);
            }

            return result;
        }

        public override BitmapFrame ReadScreenshot(IReaderState readerState)
        {
            SaveReadState state = (SaveReadState)readerState;
            if (!state.FileMetaReaded || !state.SaveMetaReaded || !state.SaveGameReaded || state.ScreenshotReaded)
                throw new InvalidOperationException();

            state.ScreenshotReaded = true;

            using (BinaryReader br = new BinaryReader(state.SaveInput, Encoding.Default, true))
            {
                int length = br.ReadInt32();
                using (StreamSegment segment = new StreamSegment(br.BaseStream, br.BaseStream.Position, length))
                {
                    PngBitmapDecoder decoder = new PngBitmapDecoder(segment, BitmapCreateOptions.IgnoreImageCache, BitmapCacheOption.OnLoad);
                    return decoder.Frames.First();
                }
            }
        }
    }
}